package com.so206.controller.payment;

import com.github.pagehelper.PageInfo;
import com.so206.controller.pay.process.UserBalnesChange;
import com.so206.plugins.pay.AliPayFunction;
import com.so206.plugins.pay.QQPayFunction;
import com.so206.plugins.pay.WxPayFunction;
import com.so206.plugins.pay.YiPayFunction;
import com.so206.po.*;
import com.so206.po.ext.SystemOrderExt;
import com.so206.service.*;
import com.so206.utils.HttpClientUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/admin/order")
public class OrderController {

    @Autowired
    private OrderService service;

    @Autowired
    private UserService userService;

    @Autowired
    private YiPayFunction yiPayFunction;

    @Autowired
    private AliPayFunction aliPayFunction;

    @Autowired
    private WxPayFunction wxPayFunctionPC;

    @Autowired
    private QQPayFunction qqPayFunction;

    @Autowired
    private UserBalnesChange userBalnesChange;

    @Autowired
    private WebConfigService webConfigService;

    @Autowired
    private AlipayConfigService alipayConfigService;

    @Autowired
    private EPayConfigService ePayConfigService;

    @Autowired
    private CodePayConfigService codePayConfigService;

    @Autowired
    private QQPayConfigService qqPayConfigService;

    @Autowired
    private WxPayConfigService wxPayConfigService;

    /**
     * 订单列表
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "20") Integer rows,
                       @RequestParam(defaultValue = "false") Boolean ajax,
                       Model model, Integer status, Long oid, HttpSession session, Integer payType, Integer order_type, String outOrderId) {
        SystemUser info = (SystemUser) session.getAttribute("userInfo");
        PageInfo<SystemOrderExt> bean;
        if (info.getRole() == 1) {
            bean = service.findByPage2(page, rows, null, status, payType, outOrderId, order_type, oid);
        } else {
            bean = service.findByPage2(page, rows, info.getId(), status, payType, outOrderId, order_type, oid);
        }
        model.addAttribute("order_type", order_type);
        model.addAttribute("bean", bean);
        model.addAttribute("oid", oid);
        model.addAttribute("status", status);
        model.addAttribute("payType", payType);
        model.addAttribute("outOrderId", outOrderId);
        if (ajax) {
            return "admin/order/list::pageNode";
        } else {
            return "admin/order/list";
        }
    }

    /**
     * 订单列表
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/list2")
    public String list2(@RequestParam(defaultValue = "1") Integer page,
                        @RequestParam(defaultValue = "20") Integer rows,
                        @RequestParam(defaultValue = "false") Boolean ajax,
                        Model model, Integer status, Long oid, Integer payType, Integer order_type, String outOrderId, Long uid) {
        PageInfo<SystemOrderExt> bean = service.findByPage2(page, rows, uid, status, payType, outOrderId, order_type, oid);
        model.addAttribute("order_type", order_type);
        model.addAttribute("bean", bean);
        model.addAttribute("status", status);
        model.addAttribute("payType", payType);
        model.addAttribute("uid", uid);
        model.addAttribute("oid", oid);
        model.addAttribute("outOrderId", outOrderId);
        if (ajax) {
            return "admin/order/list2::pageNode";
        } else {
            return "admin/order/list2";
        }
    }

    /**
     * 查看订单
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/view")
    public String view(Long id, Model model) {
        SystemOrder order = service.findOrderById(id);
        model.addAttribute("model", order);
        SystemUser systemUser = userService.findUserById(order.getUid());
        model.addAttribute("user2", systemUser);
        Integer type = order.getPayConnetType();
        Long payConnet = order.getPayConnet();
        if (type == 0) {
            EpayConfig id1 = ePayConfigService.find_by_id(payConnet);
            if (id1 != null) {
                model.addAttribute("conn", id1.getEpayName());
            } else {
                model.addAttribute("conn", "未知通道!");
            }
        } else if (type == 1) {
            CodepayConfig id1 = codePayConfigService.find_by_id(payConnet);
            if (id1 != null) {
                model.addAttribute("conn", id1.getEpayName());
            } else {
                model.addAttribute("conn", "未知通道!");
            }
        } else if (type == 2) {
            WxpayConfig id1 = wxPayConfigService.find_by_id(payConnet);
            if (id1 != null) {
                model.addAttribute("conn", id1.getEpayName());
            } else {
                model.addAttribute("conn", "未知通道!");
            }
        } else if (type == 3) {
            QqpayConfig id1 = qqPayConfigService.find_by_id(payConnet);
            if (id1 != null) {
                model.addAttribute("conn", id1.getEpayName());
            } else {
                model.addAttribute("conn", "未知通道!");
            }
        } else if (type == 4) {
            AlipayConfig id1 = alipayConfigService.find_by_id(payConnet);
            if (id1 != null) {
                model.addAttribute("conn", id1.getEpayName());
            } else {
                model.addAttribute("conn", "未知通道!");
            }
        }
        return "admin/order/view";
    }

    /**
     * 删除订单
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/delete")
    @ResponseBody
    public Map delete(Long id, HttpSession session) {
        HashMap<Object, Object> map = new HashMap<>();
        service.deleteOrder(id);
        map.put("msg", "删除成功!");
        map.put("code", 0);
        return map;
    }

    /**
     * api订单 - 补单
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/re_notify")
    @ResponseBody
    public Map renotify(Long id) {
        HashMap<Object, Object> map = new HashMap<>();
        String ret = "";
        SystemOrder order = service.findOrderById(id);
        if (order.getOrderType() == 3) {
            String url = order.getNotifyUrl();
            if (url != null) {
                try {
                    String sign = url + "?" + yiPayFunction.buildRequestParaSign(order);
                    System.out.println(sign);
                    map.put("url", sign);
                    ret = HttpClientUtils.get(sign);
                } catch (Exception e) {
                    ret = e.getMessage();
                    map.put("msg", "已重新通知系统,返回:" + ret);
                    return map;
                }
            }
        }
        map.put("msg", "已重新通知系统,返回:" + ret);
        return map;
    }

    /**
     * api订单 - 补单
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/re_notify2")
    @ResponseBody
    public Map renotify2(Long id) throws Exception {
        HashMap<Object, Object> map = new HashMap<>();
        SystemOrder order = service.findOrderById(id);
        if (order.getOrderType() == 3) {
            String url = order.getNotifyUrl();
            if (url != null) {
                String sign = url + "?" + yiPayFunction.buildRequestParaSign(order);
                map.put("url", sign);
            }
        }
        map.put("msg", "获取成功 !");
        return map;
    }

    /**
     * 退款
     */
    @RequiresPermissions("order_list")
    @RequestMapping("/refund_order")
    @ResponseBody
    public Map refund_order(Long id, HttpSession session) {
        SystemUser info = (SystemUser) session.getAttribute("userInfo");
        HashMap<Object, Object> map = new HashMap<>();
        if (info.getIsLocked() == 1) {
            map.put("msg", "账户已被锁定,无法操作!");
            map.put("code", -1);
            return map;
        }
        SystemWeb web = webConfigService.find_by_id(1L);
        if (web.getIsApiOpen() == 0) {
            map.put("msg", web.getCloseApiDetial());
            map.put("code", -1);
            return map;
        }
        SystemOrder order = service.findOrderById(id);
        if (order == null) {
            map.put("msg", "订单不存在!");
            map.put("code", -1);
            return map;
        } else {
            if (info.getRole() != 1) {
                if (!order.getUid().equals(info.getId())) {
                    map.put("msg", "订单不存在!");
                    map.put("code", -1);
                    return map;
                }
            }
            if (order.getOrderType() == 4) {
                map.put("msg", "订单不支持退款!");
                map.put("code", -1);
                return map;
            }
            if (order.getOrderType() == 2) {
                map.put("msg", "订单不支持退款!");
                map.put("code", -1);
                return map;
            }
            BigDecimal price = order.getPrice();
            BigDecimal balnes = userBalnesChange.getUserbalnes(order.getUid());
            if (info.getRole() != 1) {
                if (balnes.compareTo(price.add(order.getChangeSett())) < 0) {
                    map.put("code", -1);
                    map.put("msg", "账户余额不足,请先充值!");
                    return map;
                }
            }
            Map ret = new HashMap();
            if (order.getPayType() == 2) {//支付宝退款
                if (order.getPayConnetType() == 1 | order.getPayConnetType() == 0) {
                    map.put("msg", "码支付/易支付订单不支持退款!");
                    map.put("code", -11);
                } else {
                    Long payConnet = order.getPayConnet();
                    AlipayConfig re = alipayConfigService.find_by_id(payConnet);
                    ret = aliPayFunction.refund(order, re.getAppId(), re.getPrivateKey(), re.getPublicKey());
                }
            } else if (order.getPayType() == 1) {//微信退款
                if (order.getPayConnetType() == 1 | order.getPayConnetType() == 0) {
                    map.put("msg", "码支付/易支付订单不支持退款!");
                    map.put("code", -11);
                } else {
                    if (order.getPayConnetType() == 6) {
                        map.put("msg", "码支付/易支付订单不支持退款!");
                        map.put("code", -11);
                        return map;
                    } else {
                        WxpayConfig config = wxPayConfigService.find_by_id(order.getPayConnet());
                        ret = wxPayFunctionPC.refund(order, config.getAppId(), config.getPid(), config.getPublicKeyMch(), config.getWxCert());
                    }
                }
            } else if (order.getPayType() == 3) {//QQ退款
                if (order.getPayConnetType() == 1 | order.getPayConnetType() == 0) {
                    map.put("msg", "码支付/易支付订单不支持退款!");
                    map.put("code", -11);
                } else {
                    QqpayConfig id1 = qqPayConfigService.find_by_id(order.getPayConnet());
                    ret = qqPayFunction.refund(order, id1.getPid(), id1.getPublicKeyPwd(), id1.getPublicKeyMch(), id1.getPayCert());
                }
            }
            String msg = (String) ret.get("msg");
            Integer code = (Integer) ret.get("code");
            if (code == 0) {
                userBalnesChange.subUserBalnes(order.getUid(), price.add(order.getChangeSett()));
                map.put("msg", "提交成功,系统返回:" + msg);
                map.put("code", code);
            } else {
                map.put("msg", "提交失败,系统返回:" + msg);
                map.put("code", code);
            }
        }
        return map;
    }

    /**
     * 删除旧订单
     */
    @RequiresPermissions("admin_welcome")
    @RequestMapping("/old_clear")
    @ResponseBody
    public Map delete_old() {
        HashMap<Object, Object> map = new HashMap<>();
        Thread thread = new Thread(() -> {
            service.delete_old_data();
        });
        thread.setDaemon(true);
        thread.start();
        map.put("code", "0");
        map.put("msg", "请求已提交,请稍后刷新查看!");
        return map;
    }

}
